package com.own.business.push.module.oppo.client;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.own.business.push.core.base.BasePushClientMethod;
import com.own.business.push.core.model.MessagePushContentModel;
import com.own.business.push.module.oppo.property.PushOppoProperty;
import com.own.component.common.exception.BusinessSimpleException;
import com.own.component.common.util.encrypt.EncryptUtil;
import com.own.component.store.core.Store;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.List;
import java.util.UUID;

/**
 * PushOppoClient
 *
 * @author chenxueli
 * @date 2023-11-16 11:24:28
 */
@Slf4j
@Component
public class PushOppoClient implements BasePushClientMethod {

    private static final String HOST = "https://api.push.oppomobile.com/";
    private static final String PUSH_TOKEN_KEY = "w:c:token:oppo";

    @Resource
    private PushOppoProperty pushOppoProperty;

    @Resource
    private Store<String> store;

    /**
     * 全量推送
     *
     * @param contentModel 内容
     */
    @Override
    public void all(MessagePushContentModel contentModel) {
        log.info("oppo全量推送暂不支持");
    }

    /**
     * 注册id推送
     *
     * @param regId        注册id列表
     * @param contentModel 内容
     */
    @Override
    public void regId(String regId, MessagePushContentModel contentModel) {
        var data = new JSONObject();
        data.put("auth_token", getAuthorization());
        var message = new JSONObject();
        message.put("target_type", 2);
        message.put("target_value", regId);
        message.put("notification", buildSingleContent(contentModel));
        data.put("message", message);
        var response = HttpRequest.post(HOST + "/server/v1/message/notification/unicast")
                .contentType("application/x-www-form-urlencoded")
                .form(data)
                .execute();
        var body = response.body();
        response.close();
        log.info("oppo推送结果:{}", body);
    }

    /**
     * 注册id推送
     *
     * @param regIdList    注册id列表
     * @param contentModel 内容
     */
    @Override
    public void regId(List<String> regIdList, MessagePushContentModel contentModel) {
        var messageId = saveListPayload(contentModel);
        // 构造新的请求内容
        var data = new JSONObject();
        data.put("auth_token", getAuthorization());
        data.put("message_id", messageId);
        data.put("target_type", 2);
        data.put("target_value", String.join(";", regIdList));
        var response = HttpRequest.post(HOST + "/server/v1/message/notification/broadcast")
                .form(JSON.toJSONString(data))
                .execute();
        var body = response.body();
        response.close();
        log.info("oppo推送结果:{}", body);
    }

    /**
     * 别名推送信息
     *
     * @param alias        别名
     * @param contentModel 内容
     */
    @Override
    public void alias(String alias, MessagePushContentModel contentModel) {
        var data = new JSONObject();
        data.put("auth_token", getAuthorization());
        var message = new JSONObject();
        message.put("target_type", 5);
        message.put("target_value", alias);
        message.put("notification", buildSingleContent(contentModel));
        data.put("message", message);
        var response = HttpRequest.post(HOST + "/server/v1/message/notification/unicast")
                .contentType("application/x-www-form-urlencoded")
                .form(data)
                .execute();
        var body = response.body();
        response.close();
        log.info("oppo推送结果:{}", body);
    }

    /**
     * 别名推送信息
     *
     * @param aliasList    别名列表
     * @param contentModel 内容
     */
    @Override
    public void alias(List<String> aliasList, MessagePushContentModel contentModel) {
        var messageId = saveListPayload(contentModel);
        // 构造新的请求内容
        var data = new JSONObject();
        data.put("auth_token", getAuthorization());
        data.put("message_id", messageId);
        data.put("target_type", 5);
        data.put("target_value", String.join(";", aliasList));
        var response = HttpRequest.post(HOST + "/server/v1/message/notification/broadcast")
                .form(JSON.toJSONString(data))
                .execute();
        var body = response.body();
        response.close();
        log.info("oppo推送结果:{}", body);
    }

    /**
     * 构造推送内容（单个消息）
     *
     * @param contentModel 内容
     * @return 推送内容
     */
    private JSONObject buildSingleContent(MessagePushContentModel contentModel) {
        var data = new JSONObject();
        data.put("app_message_id", UUID.randomUUID().toString());
        data.put("title", contentModel.getNotificationTitle());
        data.put("content", contentModel.getContent());
        data.put("click_action_type", 0);
        data.put("show_start_time", 0);
        data.put("show_end_time", 0);
        data.put("action_parameters", JSON.toJSONString(contentModel.getExtras()));
        return data;
    }

    /**
     * 保存群推消息公共体接口
     *
     * @param contentModel 消息内容
     * @return 任务id
     */
    private String saveListPayload(MessagePushContentModel contentModel) {
        var data = buildSingleContent(contentModel);
        data.put("auth_token", getAuthorization());
        var response = HttpRequest.post(HOST + "/server/v1/message/notification/save_message_content")
                .contentType("application/x-www-form-urlencoded")
                .form(data)
                .execute();
        var jsonObject = JSON.parseObject(response.body());
        response.close();
        var messageId = jsonObject.getJSONObject("data").getString("message_id");
        if (StringUtils.isBlank(messageId)) {
            var message = jsonObject.getString("message");
            throw new BusinessSimpleException(StringUtils.isBlank(message) ? "保存群推消息失败" : message);
        }
        return messageId;
    }

    /**
     * 获取认证请求头
     *
     * @return 认证请求头
     */
    private String getAuthorization() {
        // 查询缓存中的token信息
        var token = store.value().get(PUSH_TOKEN_KEY);
        if (StringUtils.isNotBlank(token)) {
            return token;
        }
        var timestamp = System.currentTimeMillis();
        var sign = EncryptUtil.SHA_256.encrypt(pushOppoProperty.getKey() + timestamp + pushOppoProperty.getSecret()).toLowerCase();
        var data = new JSONObject();
        data.put("app_key", pushOppoProperty.getKey());
        data.put("timestamp", timestamp);
        data.put("sign", sign);
        // 执行请求
        var response = HttpRequest.post(HOST + "/server/v1/auth")
                .contentType("application/x-www-form-urlencoded")
                .form(data)
                .execute();
        var jsonObject = JSON.parseObject(response.body());
        response.close();
        var code = jsonObject.getInteger("code");
        if (code != 0) {
            var message = jsonObject.getString("message");
            throw new BusinessSimpleException(StringUtils.isBlank(message) ? "获取oppo推送token失败" : message);
        }
        var authToken = jsonObject.getJSONObject("data").getString("auth_token");
        if (StringUtils.isBlank(authToken)) {
            var message = jsonObject.getString("message");
            throw new BusinessSimpleException(StringUtils.isBlank(message) ? "获取oppo推送token失败" : message);
        }
        store.value().set(PUSH_TOKEN_KEY, authToken, Duration.ofHours(24));
        return authToken;
    }

    /**
     * 推送发送的名称
     *
     * @return 名称
     */
    @Override
    public String name() {
        return "oppo";
    }

}
